﻿Imports System.IO

Public Class ClsWatcher

    Public watcher As New FileSystemWatcher
    Private iDirectory As New iComm.ClsDirectory

    Sub New(ByVal strPath As String)
        '監視するディレクトリを指定
        watcher.Path = strPath
        init()
    End Sub

    Private Sub init()

        '最終アクセス日時、最終更新日時、ファイル、フォルダ名の変更を監視する
        watcher.NotifyFilter = NotifyFilters.LastAccess Or _
            NotifyFilters.LastWrite Or _
            NotifyFilters.FileName Or _
            NotifyFilters.DirectoryName
        'すべてのファイルを監視
        watcher.Filter = ""
        'UIのスレッドにマーシャリングする
        'コンソールアプリケーションでの使用では必要ない
        'watcher.SynchronizingObject = Me

        'イベントハンドラの追加
        AddHandler watcher.Created, AddressOf watcher_Changed
        AddHandler watcher.Changed, AddressOf watcher_Changed
        AddHandler watcher.Deleted, AddressOf watcher_Changed
        AddHandler watcher.Renamed, AddressOf watcher_Renamed

        '監視を開始する
        watcher.EnableRaisingEvents = True
        Console.WriteLine("監視を開始しました。")
        'サブディレクトリは監視
        watcher.IncludeSubdirectories = True
    End Sub


    'イベントハンドラ
    Private Sub watcher_Changed(ByVal sender As System.Object, _
        ByVal e As FileSystemEventArgs)
        Select Case e.ChangeType
            Case WatcherChangeTypes.Created
                Console.WriteLine(("ファイル 「" + e.FullPath + _
                    "」が作成されました。"))

                updateDB_ByWatchedProperty(e)

            Case WatcherChangeTypes.Changed
                Console.WriteLine(("ファイル 「" + e.FullPath + _
                    "」が変更されました。"))

                updateDB_ByWatchedProperty(e)

            Case WatcherChangeTypes.Deleted
                Console.WriteLine(("ファイル 「" + e.FullPath + _
                    "」が削除されました。"))

                updateDB_ByWatchedProperty(e)
        End Select
    End Sub

    Private Sub watcher_Renamed(ByVal sender As System.Object, _
        ByVal e As RenamedEventArgs)
        If e.FullPath.Equals(e.OldFullPath) AndAlso e.Name.Equals(e.OldName) Then
            Return
        End If

        Console.WriteLine(("ファイル 「" + e.FullPath + _
            "」の名前が変更されました。"))

        updateDB_ByWatchedProperty(e)
    End Sub

    Private Function updateDB_ByWatchedProperty(ByVal e As Object) As Boolean

        Dim eChanged As FileSystemEventArgs
        Dim eRenamed As RenamedEventArgs

        Dim tblInfo As DataTable

        Dim indexId As String = String.Empty

        Dim retResult As Boolean = False
        Try

            Select Case e.ChangeType
                '新規の場合'変更の場合
                Case IO.WatcherChangeTypes.Created, IO.WatcherChangeTypes.Changed

                    eChanged = e

                    tblInfo = getNewWatchedProperty(e)
                    indexId = iDirectory.getFolderOrFileId(eChanged.FullPath, tblInfo.TableName)
                    tblInfo(0).Item(0) = indexId
                    retResult = iDirectory.updateFileOrFolderToDB(tblInfo)

                    '削除の場合
                Case IO.WatcherChangeTypes.Deleted
                    eChanged = e

                    retResult = iDirectory.deleteFileOrFolderToDB(eChanged.FullPath)

                    '名前が変更の場合
                Case IO.WatcherChangeTypes.Renamed
                    eRenamed = e

                    tblInfo = getNewWatchedProperty(e)
                    indexId = iDirectory.getFolderOrFileId(eRenamed.OldFullPath, tblInfo.TableName)
                    tblInfo(0).Item(0) = indexId
                    retResult = iDirectory.updateFileOrFolderToDB(tblInfo)
                Case Else
            End Select

            Return retResult
        Catch ex As Exception
            iComm.SystemError.SystemLog(ex)
            Return False
        End Try
    End Function

    Private Function getNewWatchedProperty(ByVal e As Object) As DataTable

        Dim tblInfo As New DataTable
        Dim drRow As DataRow

        Dim dirInfo As DirectoryInfo
        Dim fInfo As FileInfo

        Dim indexId As String = String.Empty


        '変更対象はフォルダの場合
        If Directory.Exists(e.FullPath) Then
            iDirectory.initFileOrFolderTable(tblInfo)
            drRow = tblInfo.NewRow

            'indexId = iDirectory.getFolderOrFileId(e.FullPath, iComm.ClsStatic.CST_FOLDER)

            dirInfo = New DirectoryInfo(e.FullPath)

            drRow.Item(iComm.ClsDirectory.FileFormat.id.name) = indexId
            drRow.Item(iComm.ClsDirectory.FileFormat.name.name) = dirInfo.Name
            drRow.Item(iComm.ClsDirectory.FileFormat.dateCreated.name) = dirInfo.CreationTimeUtc
            drRow.Item(iComm.ClsDirectory.FileFormat.dateLastModified.name) = dirInfo.LastWriteTimeUtc
            drRow.Item(iComm.ClsDirectory.FileFormat.dateLastAccessed.name) = dirInfo.LastAccessTimeUtc

            '変更対象はファイルの場合
        Else
            fInfo = New FileInfo(e.FullPath)
            iDirectory.initFileOrFolderTable(tblInfo, True)
            drRow = tblInfo.NewRow

            'indexId = iDirectory.getFolderOrFileId(e.FullPath, iComm.ClsStatic.CST_FILE)

            drRow.Item(iComm.ClsDirectory.FileFormat.id.name) = indexId
            drRow.Item(iComm.ClsDirectory.FileFormat.name.name) = fInfo.Name
            drRow.Item(iComm.ClsDirectory.FileFormat.type.name) = fInfo.Extension
            drRow.Item(iComm.ClsDirectory.FileFormat.size.name) = fInfo.Length
            drRow.Item(iComm.ClsDirectory.FileFormat.dateCreated.name) = fInfo.CreationTimeUtc
            drRow.Item(iComm.ClsDirectory.FileFormat.dateLastModified.name) = fInfo.LastWriteTimeUtc
            drRow.Item(iComm.ClsDirectory.FileFormat.dateLastAccessed.name) = fInfo.LastAccessTimeUtc

        End If

        tblInfo.Rows.Add(drRow)

        Return tblInfo
    End Function
End Class
